import {
  getNestedRoutePath,
  route2routePath,
  useControlController,
  useNamespace,
} from '@ibiz-template/vue3-util';
import {
  defineComponent,
  onUnmounted,
  PropType,
  reactive,
  ref,
  watch,
} from 'vue';
import { IDEDRBar } from '@ibiz/model-core';
import { useRoute, useRouter } from 'vue-router';
import { IApiDRBarItemsState, IControlProvider } from '@ibiz-template/runtime';
import { isNil } from 'ramda';
import { OdooDRbarController } from './odoo-drbar.controller';
import { useAppDrBar } from './odoo-drbar-control.util';
import './odoo-drbar.scss';

export const OdooDRbarControl = defineComponent({
  name: 'IBizOdooDRbarControl',
  props: {
    /**
     * @description 数据关系栏模型数据
     */
    modelData: { type: Object as PropType<IDEDRBar>, required: true },
    /**
     * @description 应用上下文对象
     */
    context: { type: Object as PropType<IContext>, required: true },
    /**
     * @description 视图参数对象
     * @default {}
     */
    params: { type: Object as PropType<IParams>, default: () => ({}) },
    /**
     * @description 部件适配器
     */
    provider: { type: Object as PropType<IControlProvider> },
    /**
     * @description  导航数据
     */
    srfnav: { type: String, required: false },
    /**
     * @description  指定el-menu的菜单展示模式（mode）参数
     * @default vertical
     */
    showMode: { type: String, default: 'vertical' },
    /**
     * @description  隐藏编辑项
     */
    hideEditItem: { type: Boolean, default: undefined },
  },
  setup(props) {
    const c = useControlController(
      (...args) => new OdooDRbarController(...args),
    );
    const ns = useNamespace(`control-odoo-drbar`);
    const router = useRouter();
    const controlRef = ref();
    const moreRef = ref();

    const { visibleItems, moreItems, popoverVisible, setPopoverVisible } =
      useAppDrBar(c, controlRef, moreRef);

    const counterData = reactive<IData>({});
    const fn = (counter: IData) => {
      Object.assign(counterData, counter);
    };
    c.evt.on('onCounterLoadSuccess', () => {
      if (c.counter) {
        c.counter.onChange(fn, true);
      }
    });

    onUnmounted(() => {
      c.counter?.offChange(fn);
    });

    c.setRouter(router);

    const handleSelect = (key: string): void => {
      c.handleSelectChange(key);
      setPopoverVisible(false);
    };

    const handleVisibleChange = (_e: MouseEvent) => {
      _e.stopPropagation();
    };

    const route = useRoute();

    let expViewRoutePath = '';

    const opens: string[] = [];

    watch(
      () => c.state.isCreated,
      (_newVal, _oldVal) => {
        if (props.showMode !== 'horizontal') {
          const { drBarItems } = c.state;
          drBarItems.forEach(item => {
            opens.push(item.tag);
          });
        }
      },
    );

    if (c.routeDepth) {
      expViewRoutePath = getNestedRoutePath(route as any, c.routeDepth);
    }

    if (route) {
      watch(
        () => route.fullPath,
        (newVal, oldVal) => {
          if (newVal !== oldVal) {
            const depth = c.routeDepth;
            if (depth) {
              const currentRoutePath = getNestedRoutePath(
                route as any,
                c.routeDepth,
              );
              if (currentRoutePath === expViewRoutePath) {
                const routePath = route2routePath(route as any);
                const { srfnav } = routePath.pathNodes[depth! - 1];
                c.handleSelectChange(srfnav);
              }
            }
          }
        },
        { immediate: true },
      );
    }

    const renderLabel = (_item: IApiDRBarItemsState) => {
      const counterNum = _item.counterId
        ? counterData[_item.counterId]
        : undefined;
      return (
        <div class={ns.b('label')} onClick={() => handleSelect(_item.tag)}>
          {_item.sysImage && (
            <iBizIcon class={ns.be('label', 'icon')} icon={_item.sysImage} />
          )}
          <div class={ns.be('label', 'right')}>
            <div class={ns.bem('label', 'right', 'caption')}>
              {_item.caption}
            </div>
            {!isNil(counterNum) && (
              <iBizBadge
                class={ns.bem('label', 'right', 'counter')}
                value={counterNum}
                counterMode={_item.counterMode}
              />
            )}
          </div>
        </div>
      );
    };

    return {
      c,
      ns,
      moreRef,
      controlRef,
      counterData,
      visibleItems,
      moreItems,
      opens,
      popoverVisible,
      handleSelect,
      handleVisibleChange,
      renderLabel,
    };
  },
  render() {
    const { isCreated, isCalculatedPermission } = this.c.state;

    const more = (
      <el-popover
        trigger='click'
        v-model={this.popoverVisible}
        class={this.ns.b('more-dropdown')}
        popper-class={this.ns.b('more-dropdown-popper')}
      >
        {{
          reference: () => {
            return (
              <div
                ref='moreRef'
                class={[
                  this.ns.be('more-dropdown', 'link'),
                  this.ns.is('collapse', !!this.popoverVisible),
                ]}
                onClick={this.handleVisibleChange}
              >
                <span>{ibiz.i18n.t('app.more')} </span>
                <svg
                  viewBox='0 0 16 16'
                  xmlns='http://www.w3.org/2000/svg'
                  height='1em'
                  width='1em'
                >
                  <g stroke-width='1' fill-rule='evenodd'>
                    <path d='M7.978 11.997l-.005.006L2.3 6.33l.83-.831 4.848 4.848L12.826 5.5l.83.83-5.673 5.673-.005-.006z'></path>
                  </g>
                </svg>
              </div>
            );
          },
          default: () => {
            return (
              <div>
                {this.moreItems.map((_item: IApiDRBarItemsState) => {
                  return (
                    <div class={[this.ns.be('more-dropdown-popper', 'label')]}>
                      {this.renderLabel(_item)}
                    </div>
                  );
                })}
              </div>
            );
          },
        }}
      </el-popover>
    );

    return (
      <iBizControlBase ref='controlRef' controller={this.c} class={this.ns.b()}>
        {isCreated && isCalculatedPermission && (
          <el-tabs>
            {this.visibleItems.map(_tab => {
              if (_tab.visible) {
                return (
                  <el-tab-pane
                    class={this.ns.e('tab-item')}
                    label={_tab.caption || ''}
                    disabled={_tab.disabled}
                    name={_tab.tag}
                  >
                    {{
                      label: (): JSX.Element => {
                        return this.renderLabel(_tab);
                      },
                    }}
                  </el-tab-pane>
                );
              }
              return null;
            })}

            {this.moreItems.length > 0 && (
              <el-tab-pane label='' name={''}>
                {{
                  label: () => more,
                }}
              </el-tab-pane>
            )}
          </el-tabs>
        )}
      </iBizControlBase>
    );
  },
});
